/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.smarttmt.idu.web.beans;

import com.smarttmt.idu.ejb.domain.Constants;
import com.smarttmt.idu.web.behavior.Preloadable;
import com.smarttmt.idu.web.persistence.controller.ClasdoidJpaController;
import com.smarttmt.idu.web.persistence.controller.UsuacontJpaController;
import com.smarttmt.idu.web.persistence.entity.Clasdoid;
import com.smarttmt.idu.web.persistence.entity.Usuacont;
import com.smarttmt.idu.web.utilities.FacesUtils;
import com.smarttmt.idu.web.utilities.SendEmail;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.inject.Named;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.transaction.UserTransaction;
import org.primefaces.util.StringEncrypter;

/**
 *
 * @author Nicolás Rubén Caballero Ortega (helaman58@gmail.com)
 */
@Named(value = "newUserRegistryBean")
@SessionScoped
public class NewUserRegistry extends SmartIduBackingBean implements Preloadable, Serializable {

    private java.util.List<SelectItem> securityQuestionsList;
    private String userName;
    private String userEmail;
    private String userEmailConfirmation;
    private String userPassword;
    private String userPasswordConfirmation;
    private String securityQuestionSelected;
    private String responseSecurityQuestionSelected;
    private java.util.List<String> listaDocID;
    private java.util.List<SelectItem> listaDocIDSelectItem;
    @PersistenceUnit(unitName = "smarttmtiduappPU")
    private EntityManagerFactory emf;
    @Resource
    private UserTransaction utx;
    //private SendEmail sendEmail;
    private UsuacontJpaController usuacontJpaController;

    /**
     * Creates a new instance of newUserRegistry
     */
    public NewUserRegistry() {
    }

    /**
     *
     */
    @PostConstruct
    public void initpostConstructorNewUserRegistry() {
        ClasdoidJpaController cjp = new ClasdoidJpaController(utx, emf);
        java.util.List<Clasdoid> cl = cjp.findClasdoidEntities();
        buildlistaDocID(cl);

        //Inicializacion del controlador para usuarios contribuyentes
        usuacontJpaController = new UsuacontJpaController(utx, emf);
    }

    public void buildlistaDocID(java.util.List<Clasdoid> cl) {
        java.util.Iterator<Clasdoid> it = cl.iterator();
        Clasdoid aux;
        if (listaDocIDSelectItem == null) {
            listaDocIDSelectItem = new java.util.ArrayList<>();
        }

        while (it.hasNext()) {
            aux = it.next();
            listaDocIDSelectItem.add(new SelectItem(aux.getCldicodi(), aux.getCldidesc(), aux.getCldidesc()));
        }
    }

    /**
     *
     */
    public void resetData() {
        this.userName = null;
        this.userEmail = null;
        this.userEmailConfirmation = null;
        this.userPassword = null;
        this.userPasswordConfirmation = null;
        this.securityQuestionSelected = null;
        this.responseSecurityQuestionSelected = null;
    }

    @Override
    public void preload(Map<String, Object> parameters) throws Exception {
        //No se requiere necesariamente, hacer debug!
        resetData();
    }
    
    public void emailValidation(){
        compareUserEmailAndConfirmation();
        emailExist();
    }
    
    public boolean emailExist(){
        if(usuacontJpaController.getUserEmailByNomb(userEmail)!=null){
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ya existe un usuario con esa cuenta de correo electrónico", ""));
            return true;
        }else{
            return false;
        }
    }

    public void compareUserEmailAndConfirmation() {
        if (!userEmail.equalsIgnoreCase(userEmailConfirmation)) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Verificar correo electronico y Confirmacion de correo electronico", "Escriba de nuevo la informacion"));
        }
    }

    public boolean compareUserEmailAndConfirmationValidator() {
        return userEmail.equalsIgnoreCase(userEmailConfirmation);
    }

    public void compareUserPasswordAndConfirmation() {
        if (!userPassword.equalsIgnoreCase(userPasswordConfirmation)) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Verificar contrasena y Confirmacion de contrasena", "Escriba de nuevo la informacion"));
        }
    }

    public boolean compareUserPasswordAndConfirmationValidator() {
        return userPassword.equalsIgnoreCase(userPasswordConfirmation);
    }
    
    public String encryptPassword(String userPassword){
        StringEncrypter strEnc = new StringEncrypter(userPassword);
        String penc = strEnc.encrypt(userPassword);
        //System.out.println(penc);
        return penc;
    }

    public void saveNewUser() throws Exception {
        
        String newPassword = encryptPassword(userPassword);
        
        
        Usuacont usuacont = new Usuacont(new BigDecimal(1), userName, newPassword, userEmail.toLowerCase());
        usuacont.setUscoesta(Constants.USER_INACTIVE);
        usuacontJpaController.create(usuacont);
    }

    public String createNewUser() {
        userName = userName.toLowerCase();
        
        
        if (!compareUserEmailAndConfirmationValidator()) {
            compareUserEmailAndConfirmation();
            return null;
        }
        
        if (!compareUserPasswordAndConfirmationValidator()) {
            compareUserPasswordAndConfirmation();
            return null;
        }
        
        if(emailExist()){
            return null;
        }

        if (!availableUser()) {
            userNameAvailable();
            return null;
        }
        
        try {
            saveNewUser();
        } catch (Exception e) {
            //rutina en caso de excepción
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "No ha sido posible realizar su registro", "Verifique su informaciÓn e intente nuevamente"));
            return null;
        }

        if (sendEmailToActivateNewUser()) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "¡Usuario registrado exitosamente! Se envió un mensaje a su correo electrónico para que pueda iniciar su sesión", ""));
            return "userLogin";
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "No ha sido posible enviar el correo de activación de cuenta", "Verifique su información e intente nuevamente"));
            return null;
        }
    }

    public boolean sendEmailToActivateNewUser() {

        //TODO se implementa la lógica para envio de correo electrónico al usuario
        try {
            SendEmail sendEmail = (SendEmail) FacesUtils.getManagedBean("sendEmail");
            sendEmail.sendMessage(userName, Constants.ACTIVATE_FILENAME, Constants.ACTIVATE_TITLE, userEmail);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public void buildSecurityQuestions() {
        //Lógica que consulta las preguntas de seguridad y establece el list correspondiente
        //TODO A manera temporal, se genera una lista de Items
        try {
            this.securityQuestionsList = new java.util.ArrayList<>();
            this.securityQuestionsList.add(new SelectItem("1", "Nombre de tu mascota"));
            this.securityQuestionsList.add(new SelectItem("2", "Segundo nombre de tu padre"));
            this.securityQuestionsList.add(new SelectItem("3", "Segundo apellido de tu madre"));
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

    public boolean availableUser() {
        return !usuacontJpaController.existUserByNomb(userName);
    }

    public void userNameAvailable() {
        if (userName != null) {
            userName=userName.toUpperCase();
            //Se ejecuta el método que encapsula la consulta a la base de datos que valida si el usuario existe o no
            if (availableUser()) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Usuario disponible", "Usuario validado"));
            } else {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Usuario no disponible", "Escribir otro usuario"));
            }
        }
    }

    public List<SelectItem> getSecurityQuestionsList() {
        return securityQuestionsList;
    }

    public void setSecurityQuestionsList(List<SelectItem> securityQuestionsList) {
        this.securityQuestionsList = securityQuestionsList;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserEmail() {
        return userEmail;
    }

    public void setUserEmail(String userEmail) {
        this.userEmail = userEmail;
    }

    public String getUserEmailConfirmation() {
        return userEmailConfirmation;
    }

    public void setUserEmailConfirmation(String userEmailConfirmation) {
        this.userEmailConfirmation = userEmailConfirmation;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public String getUserPasswordConfirmation() {
        return userPasswordConfirmation;
    }

    public void setUserPasswordConfirmation(String userPasswordConfirmation) {
        this.userPasswordConfirmation = userPasswordConfirmation;
    }

    public String getSecurityQuestionSelected() {
        return securityQuestionSelected;
    }

    public void setSecurityQuestionSelected(String securityQuestionSelected) {
        this.securityQuestionSelected = securityQuestionSelected;
    }

    public String getResponseSecurityQuestionSelected() {
        return responseSecurityQuestionSelected;
    }

    public void setResponseSecurityQuestionSelected(String responseSecurityQuestionSelected) {
        this.responseSecurityQuestionSelected = responseSecurityQuestionSelected;
    }

    public List<String> getListaDocID() {
        return listaDocID;
    }

    public void setListaDocID(List<String> listaDocID) {
        this.listaDocID = listaDocID;
    }

    public EntityManagerFactory getEmf() {
        return emf;
    }

    public void setEmf(EntityManagerFactory emf) {
        this.emf = emf;
    }

    public UserTransaction getUtx() {
        return utx;
    }

    public void setUtx(UserTransaction utx) {
        this.utx = utx;
    }

    public List<SelectItem> getListaDocIDSelectItem() {
        return listaDocIDSelectItem;
    }

    public void setListaDocIDSelectItem(List<SelectItem> listaDocIDSelectItem) {
        this.listaDocIDSelectItem = listaDocIDSelectItem;
    }
    /*
     public SendEmail getSendEmail() {
     return sendEmail;
     }

     public void setSendEmail(SendEmail sendEmail) {
     this.sendEmail = sendEmail;
     }
     */

    public UsuacontJpaController getUsuacontJpaController() {
        return usuacontJpaController;
    }

    public void setUsuacontJpaController(UsuacontJpaController usuacontJpaController) {
        this.usuacontJpaController = usuacontJpaController;
    }

}
